#pragma once

#include "OrionFlames.h"
#include "Variation.h"

namespace OrionFlames
{
/*
  FUNKY macros to generate both C++ and GLSL versions of each Variation.
  The code is passed in as a macro argument, and either:
	substituted in verbatim (for C++)
  or	stringified with # and then returned (for GLSL)
  
  The big advantage is I can cut down on the amount of duplicated code per Variation.
*/
//#define MAKE_VARIATION(name,code,jacobian) \
//class Variation_##name : public Variation { /* class */\
//public:\
//	virtual vec2 apply(const vec2 &t) {\
//		vec2 p;\
//		{ code } \
//		return p;\
//	} \
//	virtual std::string getName() const { \
//		return #name; \
//	} \
//	virtual std::string getCode() { \
//		return #code; \
//	}\
//	virtual float getArea(const vec2 &t) {\
//		jacobian \
//	} \
//	virtual std::string getAreaCode() {\
//		return #jacobian; \
//	}\
//};

#define MAKE_VARIATION_INVERSE(name,code,icode,jacobian) \
class OFAPI Variation_##name : public Variation { \
public: \
	\
	Variation_##name()\
	{ \
		m_VariationName = std::string(#name); \
	} \
	\
	virtual vec2 apply(const vec2 &t) \
	{ \
		vec2 p; \
		{ \
			code \
		} \
		\
		return p;\
	} \
	\
	virtual std::string getName() const \
	{ \
		return m_VariationName; \
	} \
	\
	virtual std::string getCode() \
	{ \
		return #code; \
	} \
	\
	virtual vec4 sumInverse(const vec2 &p,fn_taking_vec2_t f) \
	{ \
		icode \
	} \
	\
	virtual std::string getInverseCode() \
	{ \
		return #icode; \
	}\
	\
	virtual float getArea(const vec2 &t) \
	{ \
		jacobian \
	} \
	\
	virtual std::string getAreaCode() \
	{ \
		return #jacobian; \
	}\
};
}